package fem2d;

import java.util.ArrayList;

import math2.ConstantFunctionRnToR;
import fem2.AbstractStructuralStaticDemo;
import fem2.Constraint;
import fem2.DistributedLoad;
import fem2.Edge;
import fem2.Element;
import fem2.Load;
import fem2.MaterialModel;
import fem2.Mesh;
import fem2.MeshGenerator;
import fem2.MeshPart;
import fem2.MeshUtilities;
import fem2.Model;
import fem2.Node;
import fem2.analysis.Analysis;
import fem2.analysis.LinearStaticAnalysis;
import fem2.element.EASStructuralElement;
import fem2.enu.EASModeType;
import fem2.enu.SortingCriteria;
import fem2.enu.State;
import fem2.material.StVenantKirchhoffMM;
import fem2.pre_and_post.GidMeshGenerator;

/**
 * choose each element type to get the convergence results
 * 
 * @author hbui
 * 
 */
public class CookMembraneConvergenceAnalysis extends AbstractStructuralStaticDemo {

	private String fileName;

	@Override
	public Mesh createMesh() {
		MeshGenerator mg = new GidMeshGenerator(fileName);
		Mesh mesh = mg.getMesh(2);
		return mesh;
	}

	@Override
	public Model createConditions(Model m) {
		Mesh mesh = m.getMesh();
		ArrayList<Node> leftEdge = MeshUtilities.seekNodesOnSurface(mesh, 1, 0, 0);
		ArrayList<Node> rightEdge = MeshUtilities.seekNodesOnSurface(mesh, 1, 0, -48);

		Constraint c1 = new Constraint(false, false);

		mesh.setConstraint(c1, leftEdge);

		double F = 100;

		mesh.setSortingCriteria(SortingCriteria.SORT_ON_Y_COORDINATE, rightEdge);
		for (int i = 0; i < rightEdge.size() - 1; i++) {
			Node n1 = rightEdge.get(i);
			Node n2 = rightEdge.get(i + 1);
			Edge e = mesh.addEdge(new Edge(n1, n2));
			Load l = new DistributedLoad(e, null, new ConstantFunctionRnToR(F));
			m.addLoad(l);
		}

		return m;
	}

	@Override
	public MaterialModel createMaterial(Model m) {
		double E = 250;
		double nu = 0.4999;
		MaterialModel mm = new StVenantKirchhoffMM(E, nu, 1.0, 0.0, State.PLANE_STRAIN);
		return mm;
	}

	@Override
	public Element createElement(MeshPart mp, MaterialModel mm) {
		// Element e = new StructuralElement(mp, mm);
		// e.setIntegrationType(IntegrationType.REDUCED_INTEGRATION);
		Element e = new EASStructuralElement(mp, mm, EASModeType.Q1E4);
		// Element e = new BBarStructuralElement(mp, mm);
		return e;
	}

	public void run(String fileName) {
		this.fileName = fileName;
		Model m = createModel();

		Analysis an = new LinearStaticAnalysis(m);

		an.run();

		check(m);
	}

	public void check(Model m) {
		Node n = MeshUtilities.seekNode(m.getMesh(), 48, 60);
		double[] u = n.getUHatLocal();
		System.out.println("u = [" + u[0] + ", " + u[1] + "]");
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		CookMembraneConvergenceAnalysis M = new CookMembraneConvergenceAnalysis();

		M.run("/home/hbui/kratos_janosch/cook-membrane.gid/mesh4.msh");
		M.run("/home/hbui/kratos_janosch/cook-membrane.gid/mesh9.msh");
		M.run("/home/hbui/kratos_janosch/cook-membrane.gid/mesh16.msh");
		M.run("/home/hbui/kratos_janosch/cook-membrane.gid/mesh25.msh");
		M.run("/home/hbui/kratos_janosch/cook-membrane.gid/mesh36.msh");
		M.run("/home/hbui/kratos_janosch/cook-membrane.gid/mesh49.msh");
		M.run("/home/hbui/kratos_janosch/cook-membrane.gid/mesh64.msh");
		M.run("/home/hbui/kratos_janosch/cook-membrane.gid/mesh81.msh");
		M.run("/home/hbui/kratos_janosch/cook-membrane.gid/mesh100.msh");
		M.run("/home/hbui/kratos_janosch/cook-membrane.gid/mesh121.msh");
		M.run("/home/hbui/kratos_janosch/cook-membrane.gid/mesh144.msh");
		M.run("/home/hbui/kratos_janosch/cook-membrane.gid/mesh169.msh");
	}
}
